
#include "SysHelper.h"
#include <iostream>
#include <string.h>
#include <dirent.h>
#include <unistd.h>


#include "PolarisTypedef.h"

bool CSysHelper::GetShellReturn(const std::string &strCmd, std::string &strReturn)
{
    char buffer[1024*10] = {0};
    FILE *fp = popen(strCmd.c_str(),"r");
    if (fp == NULL)
    {
        printf("CSysInfo::GetShellReturn() (fp == NULL) \n");
        return false;
    }
        
    
    strReturn.clear();
    while ( NULL != fgets(buffer, sizeof(buffer), fp) )
    {
        strReturn += buffer;
    }

    return true;
}



int CSysHelper::UtcStrTime2LocalStrTime(const char *utcStr,const char *format,char * locStr,int locStrSize)
{
    struct tm utcTm;
    struct tm locTm;
    // 根据utcStr得到utc的tm结构体
    //int milliseconds = 0;   // tm结构体没有毫秒信息，保存起来
    //sscanf(utcStrBuf,format,&(utcTm.tm_year),&(utcTm.tm_mon),&(utcTm.tm_mday),&(utcTm.tm_hour),&(utcTm.tm_min),&(utcTm.tm_sec),&milliseconds);

    sscanf(utcStr,format,&(utcTm.tm_year),&(utcTm.tm_mon),&(utcTm.tm_mday),&(utcTm.tm_hour),&(utcTm.tm_min),&(utcTm.tm_sec));
    utcTm.tm_mon -=1;
    utcTm.tm_year -=1900;

    UtcTmTime2LocalTmTime(&utcTm,&locTm);

    char tmStr[25] = {0};
    strftime(tmStr,25,"%Y/%m/%e_%H:%M:%S", &locTm);//以年月日_时分秒的形式表示当前时间
    printf("UtcStrTime2LocalStrTime() tmStr = %s\n",tmStr);

    strncpy(locStr,tmStr,locStrSize);
}

// utc时间转当地时间
int CSysHelper::UtcTmTime2LocalTmTime(struct tm *pUtcTm,struct tm *pLocTm)
{
    // 计算时区差值
    time_t now = time(NULL);

    
    struct tm tmp_UtcTm;
    struct tm tmp_LocTm;

    memset(&tmp_UtcTm,0,sizeof(tmp_UtcTm));
    memset(&tmp_LocTm,0,sizeof(tmp_LocTm));
    gmtime_r(&now,&tmp_UtcTm);
    localtime_r(&now,&tmp_LocTm);
    int dTime = difftime(mktime(&tmp_LocTm),mktime(&tmp_UtcTm));
    printf("dTime = %d\n",dTime);

/*
    struct tm {
        int tm_sec;    // Seconds (0-60) 
        int tm_min;    // Minutes (0-59) 
        int tm_hour;   // Hours (0-23) 
        int tm_mday;   // Day of the month (1-31) 
        int tm_mon;    // Month (0-11)
        int tm_year;   // Year - 1900 
        int tm_wday;   // Day of the week (0-6, Sunday = 0) 
        int tm_yday;   // Day in the year (0-365, 1 Jan = 0) 
        int tm_isdst;  // Daylight saving time 
    };
*/

    // utc的tm结构体转time_t，加上时差，得到LocalTime的time_t值
    time_t locTime = mktime(pUtcTm) + dTime;

    // time_t值转tm结构体
    memset(pLocTm,0,sizeof(struct tm));
    localtime_r(&locTime,pLocTm);

    return 0;
}



// 用于去掉Float小数数据后面的尾0 （51.20 --> 51.2）
bool CSysHelper::ParseFloatStr(const std::string& strOriginNumber, std::string& strResultNumber)
{
    std::string strTemp = strOriginNumber;
    if(strTemp.empty())
    {
        strResultNumber = strOriginNumber;
        return false;   // not Prase
    }

    int posDot = strTemp.find(".");
    if(posDot == strTemp.npos)
    {
        strResultNumber = strOriginNumber;
        return false;   // not Prase
    }

    while(!strTemp.empty())
    {
        if(strTemp.at(strTemp.length() - 1)  == '0')
        {
            strTemp.erase(strTemp.end() - 1);
            // str.pop_back();  not support
            continue;
        }
        else if(strTemp[strTemp.length() - 1] == '.')
        {
            strTemp.erase(strTemp.end() - 1);
            break;
        }
        else
            break;
    }
    strResultNumber = strTemp;
    printf("=======SysInfo::ParseFloatStr()======= Origin = %s , Result = %s\n",strOriginNumber.c_str(),strResultNumber.c_str());
    return true;
}




void CSysHelper::Struct2ConstChar()
{
    typedef struct st
    {
        int age;
        char szName[20];
        int NodeId;
        char szAddress[40];
        int classId;
    }STU_TEST;

    STU_TEST stA = {26,"Leo",1,"Guangzhou",1};
    printf("[stA] ----- age = %d, szName = %s, NodeId = %d, szAddress = %s, classId = %d\n",
            stA.age, stA.szName, stA.NodeId, stA.szAddress, stA.classId);

    char szAllInfo[512];
    memcpy(szAllInfo, (char *)&stA , sizeof(stA));
    std::string strInfo = std::string(szAllInfo);

    printf("printf (char *)&stA  = %s\n", (char *)&stA );
    printf("printf strInfo.c_str() = %s\n", strInfo.c_str());
    std::cout<<"std::cout strInfo = "<< strInfo <<std::endl;

    for(int i=0;i<sizeof(szAllInfo);i++)
    {
        printf("%c", szAllInfo[i]);
    }
    printf("\n");


    STU_TEST stB = *(STU_TEST *)szAllInfo;
    printf("[stB] ----- age = %d, szName = %s, NodeId = %d, szAddress = %s, classId = %d\n",
        stB.age, stB.szName, stB.NodeId, stB.szAddress, stB.classId);

}


// example 192.168.1.105 = 3232235881 (U32INT) (0xC0 A8 01 69) = (192 168 1 105)
int CSysHelper::Ipv4Addr2Uint32(char ipAddrStr[])
{
    UNI_U32INT_4UCHAR ipAddr;
    int i;
    printf("original Str = %s\n",ipAddrStr);
    
    sscanf(ipAddrStr,"%hhu.%hhu.%hhu.%hhu",&(ipAddr.UCharData[3]),&(ipAddr.UCharData[2]),&(ipAddr.UCharData[1]),&(ipAddr.UCharData[0]));
    //sscanf(ipAddrStr,"%d.%d.%d.%d",&(ipAddr.UCharData[3]),&(ipAddr.UCharData[2]),&(ipAddr.UCharData[1]),&(ipAddr.UCharData[0]));
    //sscanf(ipAddrStr,"%d.%d.%d.%d",&(ipAddr.UCharData[0]),&(ipAddr.UCharData[1]),&(ipAddr.UCharData[2]),&(ipAddr.UCharData[3]));

    printf("ipv4Addr2Uint32() \n");
    for(i=3;i>=0;i--)
    {
        printf("[%d] = %hhu\t",i,ipAddr.UCharData[i]);
    }
    printf("\n int = %u\n",ipAddr.U32Data);
    
}

bool CSysHelper::GetPathFileLists(const std::string path,const std::list<std::string> lists)
{
    if(path.empty())
    {
        return false;
    }

    if( access(path.c_str(),F_OK) !=0)
    {
        return false;
    }
    DIR *dp = opendir(path.c_str());
    struct  dirent *ep = NULL;
    while (true)
    {
        ep = readdir(dp);
        if(ep == NULL)
        {
            if(errno ==0)
            {
                // EOF , finish
                break;
            }
            else
            {
                perror("readdir error");
                break;
            }
        }
        else
        {
            // ignore . and  .. 
            if(ep->d_name[0] == '.')
            {
                continue;
            }
            printf("%s\n",ep->d_name);
        }
        
    }

    closedir(dp);
    return true;
}

